/* 拓扑排序
* 1.做法:
    (1) 合并两个集合
    (2) 查询某个元素的祖宗节点
    (3) 记录方法:
        记录每个集合大小: 绑定到根节点上
        记录每个点到根节点的距离: 绑定到每个元素上

* 2.离散化:
    (1) 保留排序: 排序，判重，二分
    (2) 不保留排序: map, hash

* 本题: 
    带权并查集 权值: 当前点到根的战舰数量 
    M a b 拼接:第一棵树插到第二颗树上, a拼到b的下面, a到fa[a]的距离全部加上sz[b]
*/

#pragma GCC optimize("O1,O2,O3,Ofast")
#pragma GCC optimize("no-stack-protector,unroll-loops,fast-math,inline")
#pragma GCC target("avx,avx2,fma")
#pragma GCC target("sse,sse2,sse3,sse4,sse4.1,sse4.2,ssse3")

#include <iostream>
#include <cstring>
#include <algorithm> 
#include <vector>
#include <unordered_map>
// #define ONLINE_GUDGE
using namespace std;
const int N = 30010;

int n = 30000, m;
int fa[N], d[N], sz[N]; // d[i]:x到fa[i]的距离 sz[i]:集合大小

inline int find(int x)
{
    if(fa[x] != x){
        int fx = find(fa[x]);
        d[x] += d[fa[x]]; // x所在列全部加上fa[x]的距离
        fa[x] = fx;
    }
    return fa[x];
}

int main()
{

    #ifdef ONLINE_JUDGE
    ios::sync_with_stdio(false);   
	cin.tie(0);
    #else
    freopen("./in.txt","r",stdin);
    #endif
    cin >> m;
    for (int i = 1;i <= n;i++) fa[i] = i, sz[i] = 1;

    while(m--){
        int i, j; char op;
        cin >> op >> i >> j;

        int fi = find(i), fj = find(j);
        if(op == 'M'){ // M i j i拼到j下面
             if(fi != fj){
                fa[fi] = fj;
                d[fi] = sz[fj]; // a到根的距离等于j的大小
                sz[fj] += sz[fi]; // j下面多拼了所有的a
             }
        }
        else{
            if(fi != fj) cout << -1 << endl;
            else cout << max(0, abs(d[i] - d[j]) - 1) << endl;
        }

    }
    
    return 0;
}
